package client;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

import databases.MongoDB;
import databases.MySQL;
import utilities.ANSI;
import utilities.Console;

/**
 * The Class ClientWorker.
 * 
 * @author Nils Berlijn
 * @author Henderikus Harms
 * @version 1.0
 * @since June 1, 2014
 */
public class ClientWorker implements Runnable 
{
	/** The client socket. */
	private Socket clientSocket;
	
	/** The client worker socket. */
	private InetAddress clientWorkerSocket;
	
	/** The input. */
	private Scanner input;	
	
	/** The output. */
	private PrintWriter output;	
	
	/** The command. */
	private String command;
	
	/** The console. */
	private Console console;

	/**
	 * Instantiates a new client worker.
	 *
	 * @param clientSocket the client socket
	 */
	public ClientWorker(Socket clientSocket)
	{
		this.clientSocket = clientSocket;
		this.clientWorkerSocket = clientSocket.getInetAddress();

		try
		{
			this.input = new Scanner(clientSocket.getInputStream());
			this.output = new PrintWriter(clientSocket.getOutputStream(), true);
			this.console = new Console(input, output);
			
			MySQL.console(console);
			MongoDB.console(console);
		}
		catch(Exception e)
		{
			
		} 	
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run()
	{
        System.out.println(ANSI.BLUE + "Client Worker: " + ANSI.GREEN + "Executing \"" + Thread.currentThread().getName() + "\"" + ANSI.NORMAL);
        
        console(); 		    
	}
	
	/**
	 * Client worker socket.
	 *
	 * @return the inet address
	 */
	public InetAddress clientWorkerSocket()
	{
		return clientWorkerSocket;	
	}	
	
	/**
	 * Console.
	 */
	private void console()
	{
		console.write(ANSI.GREEN + "\n Welcome to the UNWDMI application" + ANSI.NORMAL);	
		console.pursue();	
		menu();
	}
	
	/**
	 * Menu.
	 */
	private void menu()
	{
		console.write(ANSI.GREEN + "\n Please make a choice out one of these options:\n" + ANSI.NORMAL);
		
		console.write(ANSI.YELLOW + " [A] Get Weather Station by station nnumber" + ANSI.NORMAL);
		console.write(ANSI.YELLOW + " [B] Get Weather Stations by country" + ANSI.NORMAL);
		console.write(ANSI.YELLOW + " [C] Get Measurements by station number" + ANSI.NORMAL);
		console.write(ANSI.YELLOW + " [D] Get Measurements by country" + ANSI.NORMAL);	
		console.write(ANSI.YELLOW + " [E] Get Measurements last day by country" + ANSI.NORMAL);	
		console.write(ANSI.YELLOW + " [F] Get first Measurement" + ANSI.NORMAL);
		console.write(ANSI.YELLOW + " [G] Get latest Measurement" + ANSI.NORMAL);			
		
		console.write(ANSI.YELLOW + "\n [EXIT] Close the connection\n" + ANSI.NORMAL);		
		
		command = console.read("Command", ANSI.GREEN + " Choice: " + ANSI.GREEN);
		
		String stn = "";
		String amount = "";
		String country = "";
		String amountWeatherStations = "";
		String amountMeasurements = "";
		
		switch(command)
		{
			case "A":
				stn = console.read("Command", ANSI.GREEN + " Station: " + ANSI.GREEN);				
				MySQL.selectWeatherStationByStn(Integer.parseInt(stn));
				console.pursue();
				menu();
				break;	
			case "B":
				country = console.read("Command", ANSI.GREEN + " Country: " + ANSI.GREEN);
				amount = console.read("Command", ANSI.GREEN + " Amount: " + ANSI.GREEN);				
				MySQL.selectWeatherStationByCountry(country, Integer.parseInt(amount));
				console.pursue();
				menu();
				break;						
			case "C":
				stn = console.read("Command", ANSI.GREEN + " Station: " + ANSI.GREEN);
				amount = console.read("Command", ANSI.GREEN + " Amount: " + ANSI.GREEN);
				MongoDB.selectMeasurementsByStn(Integer.parseInt(stn), Integer.parseInt(amount));
				console.pursue();
				menu();	
				break;	
			case "D":
				country = console.read("Command", ANSI.GREEN + " Country: " + ANSI.GREEN);
				amountWeatherStations = console.read("Command", ANSI.GREEN + " Amount Weather Stations: " + ANSI.GREEN);
				amountMeasurements = console.read("Command", ANSI.GREEN + " Amount Measurements: " + ANSI.GREEN);
				MongoDB.selectMeasurementsByCountry(country, Integer.parseInt(amountWeatherStations), Integer.parseInt(amountMeasurements));
				console.pursue();
				menu();	
				break;
			case "E":
				country = console.read("Command", ANSI.GREEN + " Country: " + ANSI.GREEN);
				amountWeatherStations = console.read("Command", ANSI.GREEN + " Amount Weather Stations: " + ANSI.GREEN);
				amountMeasurements = console.read("Command", ANSI.GREEN + " Amount Measurements: " + ANSI.GREEN);
				MongoDB.selectMeasurementsLastDayByCountry(country, Integer.parseInt(amountWeatherStations), Integer.parseInt(amountMeasurements));
				console.pursue();
				menu();	
				break;					
			case "F":
				MongoDB.selectFirstMeasurement();
				console.pursue();
				menu();
				break;				
			case "G":	
				MongoDB.selectLatestMeasurement();
				console.pursue();
				menu();
				break;	
			case "EXIT":
				exit();
				break;	
			default:
				console.error();
				console.pursue();
				menu();
				break;
		}		
	}
	
	/**
	 * Exit.
	 */
	private void exit()
	{
		try
		{
			console.write(ANSI.YELLOW + "\n Closing the connection..." + ANSI.NORMAL);	
			console.writeCommand("\n ");
			
			Thread.sleep(1000);
			
	        System.out.println(ANSI.BLUE + "Client Worker: " + ANSI.GREEN + "Finished \"" + Thread.currentThread().getName() + "\"" + ANSI.NORMAL);
	       
	        try
	        {
		        clientSocket.close();
				
		        System.out.println(ANSI.BLUE + "Client Worker: " + ANSI.YELLOW + "Disconnecting \"" + clientWorkerSocket() + "\"" + ANSI.NORMAL);	        	
	        }	
	        catch(IOException e)
	        {
	        	
	        }			
		}
		catch(InterruptedException e)
		{
			
		}			
	}
}